package com.andatsoft.laisim.view;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import org.htmlcleaner.BaseTokenImpl;
import org.htmlcleaner.CleanerProperties;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.TagNode;
import org.htmlcleaner.XPatherException;

import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.widget.ScrollView;
import android.widget.TextView;

import com.andatsoft.laisim.R;
import com.andatsoft.laisim.activity.EditLyricsActivity;
import com.andatsoft.laisim.activity.MainActivity;
import com.andatsoft.laisim.db.DataBaseAccess;
import com.andatsoft.laisim.dialog.LyricsGettingDialog;
import com.andatsoft.laisim.theme.Theme;
import com.andatsoft.laisim.theme.ThemeManager;
import com.andatsoft.laisim.utils.Common;
import com.andatsoft.laisim.utils.Utils;
import com.andatsoft.laisim.view.SlimProgressBar.SlimProgressClicked;
import com.nineoldandroids.view.ViewHelper;

public class MainLyricsFragment extends Fragment {

	private TextView mTvLyrics;
	private ScrollView mScrollView;
	private int mSongId;
	private Point mToolBoxPosition;
	private View mLayoutBg;
	private float mAlpha;

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View view = inflater.inflate(R.layout.pager_main_lyrics, container,
				false);
		mTvLyrics = (TextView) view
				.findViewById(R.id.tv_pager_main_song_lyrics);

		mScrollView = (ScrollView) view.findViewById(R.id.scroll_lyrics);

		mTvLyrics.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View arg0, MotionEvent e) {
				if (e.getAction() == MotionEvent.ACTION_DOWN) {
					if (mToolBoxPosition == null)
						mToolBoxPosition = new Point();
					mToolBoxPosition.x = (int) e.getX() + mTvLyrics.getLeft();
					mToolBoxPosition.y = (int) e.getY()
							- mScrollView.getScrollY() + mTvLyrics.getTop();

				}
				return false;
			}
		});
		mTvLyrics.setOnLongClickListener(new OnLongClickListener() {

			@Override
			public boolean onLongClick(View v) {
				mSongId = ((MainActivity) getActivity()).getCurrentSongId();

				Rect r = new Rect();
				mTvLyrics.getGlobalVisibleRect(r);
				if (mTvLyrics.getTop() < 10) {
					getMainActivity().doLaisimAnimation(mToolBoxPosition.x,
							mToolBoxPosition.y + r.top);
				} else {
					getMainActivity().doLaisimAnimation(mToolBoxPosition.x,
							mToolBoxPosition.y + (r.top - mTvLyrics.getTop()));
				}

				showToolBox();
				return false;
			}
		});
		mLayoutBg = view.findViewById(R.id.layout_main_pager_lyrics);
		return view;
	}

	@Override
	public void onResume() {
		super.onResume();
		applyTheme();
	}

	private void applyTheme() {
		Theme theme = ThemeManager.getSelectedTheme();
		mTvLyrics.setTextColor(theme.getMPLSColor());
		mTvLyrics.setTextSize(theme.getMPLSSize());
		mAlpha = ThemeManager.getSelectedTheme().getMPLSAlpha();
		setAlpha(mLayoutBg, mAlpha);
		mLayoutBg.setBackgroundColor(theme.getMainBackgroundColor());
	}

	public Fragment getInstance() {
		return this;
	}

	private MainActivity getMainActivity() {
		return (MainActivity) getActivity();
	}

	@SuppressLint("NewApi")
	protected void setAlpha(View view, float alpha) {
		if (Utils.androidOs > Common.ANDROID_OS_GINGERBREAD) {
			view.setAlpha(alpha);
		} else {
			ViewHelper.setAlpha(view, alpha);
		}
	}

	private void setBgColor(View v) {
		v.setBackgroundColor(ThemeManager.getSelectedTheme()
				.getDialogBackgroundColor() | 0xff000000);
	}

	private boolean isSongHasLyrics(int songId) {
		DataBaseAccess db = DataBaseAccess.getInstance(getActivity()
				.getApplicationContext());
		boolean re = db.isSongHasLyrics(songId);
		return re;
	}

	private void showToolBox() {
		final Toolbox toolBox = getMainActivity().getToolBox();

		if (toolBox == null)
			return;
		toolBox.setContentLayout(R.layout.tool_box_lyrics);
		toolBox.show();
		final TextView btnUpdateLyrics = (TextView) toolBox
				.findViewById(R.id.btn_lyrics_update);
		btnUpdateLyrics.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());
		setBgColor(btnUpdateLyrics);
		btnUpdateLyrics.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnUpdateLyrics.setEnabled(false);
					updateLyrics(mSongId);
					toolBox.close();
					return true;
				}
				return false;
			}
		});

		final TextView tvBg = (TextView) toolBox
				.findViewById(R.id.tv_lyrics_transparent_background);

		tvBg.setTextColor(ThemeManager.getSelectedTheme().getNormalTextColor());
		final SlimProgressBar progressBg = (SlimProgressBar) toolBox
				.findViewById(R.id.progress_lyrics_transparent_background);
		progressBg.setBackgroundWidth(6f);
		progressBg.setProgressWidth(4f);
		progressBg.setMax(100);
		progressBg.setProgress((int) (mAlpha * 100));
		progressBg.setOnSlimClicked(new SlimProgressClicked() {

			@Override
			public void onClick(int newProgress) {
				mAlpha = ((float) newProgress) / 100;
				setAlpha(mLayoutBg, mAlpha);
			}
		});

		final TextView btnEditLyrics = (TextView) toolBox
				.findViewById(R.id.btn_lyrics_edit);
		setBgColor(btnEditLyrics);
		setBgColor(toolBox
				.findViewById(R.id.layout_lyrics_transparent_background));
		btnEditLyrics.setTextColor(ThemeManager.getSelectedTheme()
				.getNormalTextColor());

		btnEditLyrics.setOnTouchListener(new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					break;
				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().doLaisimAnimation(v);
					btnEditLyrics.setEnabled(false);
					editLyrics(mSongId);
					toolBox.close();
					break;
				}
				return true;
			}
		});
		final TextView btnRemoveLyrics = (TextView) toolBox
				.findViewById(R.id.btn_lyrics_remove);
		setBgColor(btnRemoveLyrics);
		if (!isSongHasLyrics(mSongId)) {
			// btnEditLyrics.setVisibility(View.GONE);
			btnRemoveLyrics.setVisibility(View.GONE);
			toolBox.findViewById(R.id.layout_lyrics_transparent_background)
					.setVisibility(View.GONE);

		} else {

			btnRemoveLyrics.setTextColor(ThemeManager.getSelectedTheme()
					.getNormalTextColor());

			btnRemoveLyrics.setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View v, MotionEvent event) {
					switch (event.getAction()) {
					case MotionEvent.ACTION_DOWN:
						setAlpha(v, 0.5f);
						break;
					case MotionEvent.ACTION_UP:
						setAlpha(v, 1.0f);
						getMainActivity().doLaisimAnimation(v);
						btnRemoveLyrics.setEnabled(false);
						removeLyrics(mSongId);
						toolBox.close();
						break;
					}
					return true;
				}
			});

		}

		if (mToolBoxPosition.x > mScrollView.getWidth() / 3) {
			mToolBoxPosition.x /= 2;
		}

		toolBox.getContent().setPadding(0, mToolBoxPosition.y, 0, 0);
	}

	public void editLyrics(int songId) {
		Intent i = new Intent(getActivity(), EditLyricsActivity.class);
		i.putExtra(Common.SONG_ID_INTENT, mSongId);
		i.putExtra(Common.SONG_LYRICS_INTENT, mTvLyrics.getText());
		startActivityForResult(i, Common.REQUEST_CODE_FOR_LYRICS_EDITOR);
	}

	public void updateLyrics(int songId) {
		String title = ((MainActivity) getActivity()).getCurrentSongTitle();
		if (title == null)
			return;
		Intent i = new Intent(getActivity(), LyricsGettingDialog.class);
		i.putExtra(Common.SONG_TITLE_INTENT, title);
		startActivityForResult(i, Common.REQUEST_CODE_FOR_LIST_DIALOG);
	}

	public void removeLyrics(int songId) {
		String delMess = getString(R.string.mpsl_message_remove_lyrics);
		OnTouchListener okEvent = new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (!getMainActivity().isCanClickMessageBox()) {
					return true;
				}
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().deleteSongLyrics(mSongId);
					setLyrics(getString(R.string.mpsl_lyrics_empty));
					getMainActivity().setCanClickMessageBox(false);
					cancelMessageBox();
					break;
				}
				return false;

			}
		};

		OnTouchListener cancelEvent = new OnTouchListener() {

			@Override
			public boolean onTouch(View v, MotionEvent event) {
				if (!getMainActivity().isCanClickMessageBox()) {
					return true;
				}
				switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					setAlpha(v, 0.5f);
					return true;

				case MotionEvent.ACTION_UP:
					setAlpha(v, 1.0f);
					getMainActivity().setCanClickMessageBox(false);
					cancelMessageBox();
					break;
				}
				return false;
			}
		};
		showMessageBox(delMess, okEvent, cancelEvent);
	}

	private void cancelMessageBox() {
		getMainActivity().dismissMessageBox();
	}

	private void showMessageBox(String content, OnTouchListener okEvent,
			OnTouchListener cancelEvent) {
		getMainActivity().showMessageBox(content, okEvent, cancelEvent);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if (requestCode == Common.REQUEST_CODE_FOR_LIST_DIALOG) {
			if (resultCode == 0)// Cancel
			{
				// getMainActivity().setNeedUpdateLyrics(false);
				// if (!isSongHasLyrics(mSongId))
				// setLyrics(getString(R.string.mpsl_lyrics_empty));
			} else if (resultCode == Common.RESULT_CODE_FOR_LYRICS_FRAGMENT) {
				String url = data
						.getStringExtra(Common.RESULT_INTENT_FOR_LYRICS_FRAGMENT);
				((MainActivity) getActivity()).setNeedUpdateLyrics(false);
				new LyricsGetter().execute(url);

			}
		}
		if (requestCode == Common.REQUEST_CODE_FOR_LYRICS_EDITOR) {
			if (resultCode == 0)// Cancel
			{
			} else if (resultCode == Common.RESULT_CODE_FOR_LYRICS_FRAGMENT_FROM_LYRICS_EDITOR) {
				getMainActivity().requestUpdateLyrics();
			}

		}
	}

	boolean isAnimEnded = false;

	@SuppressLint("NewApi")
	public void setLyrics(final String lyrics) {

		if (Utils.androidOs < Common.ANDROID_OS_GINGERBREAD_TO_ICS) {
			com.nineoldandroids.animation.ObjectAnimator o = com.nineoldandroids.animation.ObjectAnimator
					.ofFloat(mTvLyrics, "alpha", 1.0f, 0.0f);
			o.setDuration(500);
			o.addListener(new com.nineoldandroids.animation.Animator.AnimatorListener() {

				@Override
				public void onAnimationStart(
						com.nineoldandroids.animation.Animator arg0) {
				}

				@Override
				public void onAnimationRepeat(
						com.nineoldandroids.animation.Animator arg0) {
				}

				@Override
				public void onAnimationEnd(
						com.nineoldandroids.animation.Animator anim) {
					if (lyrics == null || lyrics.equals("")) {
						mTvLyrics
								.setText(getString(R.string.mpsl_lyrics_empty));
					} else {
						mTvLyrics.setText(lyrics);
					}
					anim = com.nineoldandroids.animation.ObjectAnimator
							.ofFloat(mTvLyrics, "alpha", 0.0f, 1.0f);
					anim.setDuration(500);
					anim.start();
				}

				@Override
				public void onAnimationCancel(
						com.nineoldandroids.animation.Animator arg0) {

				}
			});
			o.start();
		} else {
			ObjectAnimator o = ObjectAnimator.ofFloat(mTvLyrics, "alpha", 1.0f,
					0.0f);
			o.setDuration(500);
			o.addListener(new AnimatorListener() {

				@Override
				public void onAnimationStart(
						android.animation.Animator animation) {

				}

				@Override
				public void onAnimationRepeat(
						android.animation.Animator animation) {

				}

				@Override
				public void onAnimationEnd(android.animation.Animator animation) {
					// if (isAnimEnded)
					// return;
					isAnimEnded = true;
					if (lyrics == null) {
						mTvLyrics
								.setText(getString(R.string.mpsl_lyrics_empty));
					} else {
						mTvLyrics.setText(lyrics);
					}
					Log.d("anim", lyrics);
					animation.removeAllListeners();
					animation = ObjectAnimator.ofFloat(mTvLyrics, "alpha",
							0.0f, 1.0f);
					animation.setDuration(500);
					animation.start();
				}

				@Override
				public void onAnimationCancel(
						android.animation.Animator animation) {

				}
			});
			o.start();
		}

	}

	private String getURLId(String src) {
		String re = src.substring(src.lastIndexOf("/") + 1,
				src.lastIndexOf(".html"));
		return re;
	}

	private String editLine(String line) {
		if (line == null)
			return "";
		line = line.trim();
		if (line.equals("br")) {
			return "\n";
		}
		if (line.equals("span")) {
			return "";
		}
		return line;
	}

	class LyricsGetter extends AsyncTask<String, Void, String> {

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			mTvLyrics.setText(getString(R.string.mpsl_message_getting_lyrics));
		}

		@Override
		protected String doInBackground(String... params) {
			String src = params[0];
			try {
				URL url = new URL(src);
				HtmlCleaner html = new HtmlCleaner();
				CleanerProperties props = html.getProperties();
				props.setAllowHtmlInsideAttributes(true);
				props.setAllowMultiWordAttributes(true);
				props.setRecognizeUnicodeChars(true);
				props.setOmitComments(true);

				TagNode node = html.clean(url);
				String xPathExpression = "//div[@id='_lyricContainer"
						+ getURLId(src) + "']//p";

				Object[] obj = node.evaluateXPath(xPathExpression);
				if (obj == null || obj.length <= 0)
					return null;
				TagNode lyricTag = (TagNode) obj[0];
				@SuppressWarnings("unchecked")
				List<BaseTokenImpl> content = (List<BaseTokenImpl>) lyricTag
						.getAllChildren();
				StringBuilder result = new StringBuilder();
				for (int i = 0; i < content.size(); i++) {
					String line = content.get(i).toString();
					line = editLine(line);
					// Log.d("Lyrics", line);
					result.append(line);
				}

				return result.toString();
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (XPatherException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return null;
		}

		@Override
		protected void onPostExecute(String result) {
			if (result == null) {
				mTvLyrics
						.setText(getString(R.string.mpsl_message_error_getting_lyrics));
			} else {
				setLyrics(result);
				// mTvLyrics.setText(result);
				// update db
				((MainActivity) getActivity())
						.updateSongLyrics(mSongId, result);
				((MainActivity) getActivity()).setNeedUpdateLyrics(true);
			}
		}
	}

	// //////////////////////////////////
	//
	// DB
	//
	// /////////////////////////////////

}
